<template>
    <el-container class="bk_full_wapper">
  <el-header class="height_auto"><h2>{{ name }}</h2></el-header>
  <el-main>

    <vue-magic-tree
      :setting="setting"
      @onCreated="handleCreated"
      @onAsyncSuccess="zTreeOnAsyncSuccess"
      ref='tree'
    />

    </el-main>
      <div @contextmenu.prevent="onContextmenu" />
</el-container>
</template>

<script>

import '@/assets/ztree/css/iconfont/iconfont.css'
import '@/assets/ztree/css/zTreeStyle/zTreeStyle.css'
import $ from 'jquery'
import _ from 'lodash'

if (!window.jQuery) {
  window.jQuery = $  //:nodes="treeData"
}
import VueMagicTree from '@/components/vue-magic-tree/src/components/ztree.vue'
import SnowflakeId from 'snowflake-id'
import request from '@/utils/requestutil'
import {getRealUrl} from '@/utils/httpRequet'
export default {
  name: 'VuePsTree',
  components: {
    VueMagicTree
  },
  props: {
    treeCompData: {
      type: Object,
      default: () => {
        return {
          name: '', // 填写标注
          treeData: [],
          treeBuildConfig: {},

        }
      }
    }
  },
  data() {
    return {
      dataUrl: "",// getRealUrl('normalDicTree',true)  ,
      treeConfigKey:null,
      treeconfigurl:'treeConfigUrl',
      treeConfig:{},
      level:"",
      mode: 'manual',
      name: '',
      key: '',
      edit: true,
      drag: false,
      curDragNodes: null,
      checkType: 'no',
      autoExpandNode: null,
      ztreeObj: null,
      newCount: 1,
      editShowType: '2',
      setting: {
        edit: {
          enable: true,
          showRenameBtn: false,
          showRemoveBtn:false,
          drag: {
            isCopy: false,
            isMove: true
          }
        },
        options: {},
        data: {
          // 设置图标库(采用iconfont class形式)
          iconMap: {
            zzxlxwjygl_Cls: 'icon-zzxlxwjygl_Cls',
            rs_dw_Cls: 'icon-rs_dw_Cls',
            dash_Cls: 'icon-dash-line',
            qzkj_Cls:'icon-qzkj_Cls',
            menu_formman_cls:'icon-menu_formman_cls',
            meta_same:'icon-meta_same',
            folder:'icon-folder',
            leaf:'icon-leaf',
          },
          // 设置对应每个节点的节点类型，与数据中customType属性对应
          key: {
            nodeType: 'iconcls'
          },
          simpleData: {
            enable: true,
            idKey: 'id',
            pIdKey: 'pid',
            rootPId: ''
          }
        },
        view: {
          // 开启图标显示功能
          showIcon: true,
          selectedMulti:false,
        },
        check: {
          /**
           *
           Y 属性定义 checkbox 被勾选后的情况；
           N 属性定义 checkbox 取消勾选后的情况；
           "p" 表示操作会影响父级节点；
           "s" 表示操作会影响子级节点。
           请注意大小写，不要改变
           */
          chkboxType: { 'Y': 'ps', 'N': 's' },
          enable: false
        },
        callback: {
          onCheck:this.onTreeCheck,
          // 1. 每次点击 checkbox 或 radio 后， 弹出该节点的 tId、name 以及当前勾选状态的信息
          onClick: this.onTreeClick,
          // 1. 每次折叠节点后， 弹出该节点的 tId、name 的信息
          onCollapse: this.onTreeCollapse,
          // 1. 每次鼠标双击后， 弹出鼠标所在节点的 tId、name 的信息
          onDblClick: this.onTreeDblClick,
          // 1. 每次开始进行拖拽节点后， 弹出被拖拽节点的个数信息
          onDrag: this.onTreeDrag,
          // 1. 拖拽节点时，随时输出 当前拖拽到的目标 DOM
          onDragMove: this.onTreeDragMove,
          // 1. 每次拖拽操作结束后， 弹出该被拖拽节点的个数以及目标节点的 tId、name 的信息
          onDrop: this.onTreeDrop,
          // 1. 每次展开节点后， 弹出该节点的 tId、name 的信息
          onExpand: this.onTreeExpand,
          // 1. 每次鼠标按键按下后， 弹出鼠标所在节点的 tId、name 的信息
          onMouseDown: this.onTreeMouseDown,
          // 1. 每次鼠标按键松开后， 弹出鼠标所在节点的 tId、name 的信息
          onMouseUp: this.onTreeMouseUp,
          // 1. 每次鼠标右键点击后， 弹出鼠标所在节点的 tId、name 的信息
          onRightClick: this.onTreeRightClick,
          // onAsyncSuccess ztree加载成功之后的回调函数
          onAsyncSuccess: this.zTreeOnAsyncSuccess,
          beforeDrop:this.beforeDrop,
          beforeDrag:this.beforeDrag,
          //双击之前和之后函数
          beforeDblClick:this.beforeDblClick,
          onDblClick:this.onDblClick,
        },
        async: {
          autoParam: function(treeid,node){
            return ["id=pid"]
            },
          contentType: 'application/x-www-form-urlencoded',
          dataFilter: function(treeid,pnode,resdata){
            return resdata;
          },
          dataType: 'text',
          otherParam: this.initBaseparam,
          type: 'post',
          headers: {},
          dataRoot:'data',
          xhrFields: {},
          url: this.dataUrl,
          enable: false
        }
      },
      treeData: []
    }
  },
  watch: {
    // treeConfigKey:{
    //   handler(val){
    //     this.cfgloaded=false;
    //     this.loadConfig();
    //   },
    //   immediate:true,
    // },
    treeCompData: {
      handler(val, oldVal) {
        this.initSettings(val)
      },
      deep: true, // true 深度监听
      immediate: true
    },
    // dataUrl: {
    //   handler(val) {
    //     if (val && val !='defaultTreeDataUrl') {
    //       this.cfgloaded=true;
    //       this.setting.async.enable=true;
    //       let $t=this;
    //       // setTimeout(function(){
    //       //   $t.loadTree.call($t);
    //       // },20)
    //       //this.loadTree()
    //     }else{
    //       //this.refresh();
    //     }
    //   },
    //   immediate: true
    // }
  },
  created() {
  },
  methods: {
    zTreeOnAsyncSuccess(event, treeId, treeNode, msg) {
      this.$emit('onAsyncSuccess', ...arguments)
    },
    // onTreeRightClick() {
    //   this.$emit('onTreeRightClick', [...arguments])
    // },
    initBaseparam(treeid,node){
      return{templet:this.treeConfig.queryTemplet,level:this.level!="" ? this.level : "SUB"}
    },
    reload(nodeid){
      if(_.isEmpty(nodeid))nodeid="";
       const $t = this
      // request({
      //         url: this.dataUrl,
      //         method:'post',
      //         data:{pid:nodeid,templet:this.treeConfig.queryTemplet,level:'SUB'}
      //       }).then((res) => {
      //         if (res.data && res.data.length > 0) {
      //           res.data.map(item=>{
      //             item.isParent=true;
      //           })
      //           $t.treeData = res.data
      //         } else {
      //           $t.treeData = [{ id: 'root', pid: '0', name: '根节点' }]
      //         }
      //       })
    },
    // 加载树配置
    loadConfig(){
      if(_.isEmpty(this.treeConfigKey))return;
      request({
          url: this.treeconfigurl,
          data:{flag:this.treeConfigKey},
          method:'post'
        }).then(dt=>{
          if(dt.category){
            let async=this.async||dt.category.requestFlag=='Y'
            if(!this.async){
              this.loadTreeData(dt.category);
              return;
            }
            this.treeConfig=dt.category;
            this.cfgloaded=true;
            this.setting.async.enable=true;
            this.setting.async.url=this.dataUrl;
          }
        })
    },
    // 加载树数据
    loadTreeData(treeConfig){
      if(_.isEmpty(treeConfig.queryTemplet))return
      request({
        url: this.dataUrl,
        method:'post',
        // 'ALL' 表示查询整个数
        data:{pid:"",templet:treeConfig.queryTemplet,level:'ALL'}
      }).then(data=>{
        if(data.data){
          this.treeData=data.data;
          let $t=this;
          setTimeout(
          function(){
            $t.$refs.tree.loadData(data.data);
          },20
        )
        }
      })
    },
    loadTree() {
      if(this.treeConfigKey &&!this.cfgloaded){
        this.loadConfig()
        return;
      }
      this.refresh();
    },
    initSettings(_val) {
      const val = _.cloneDeep(_val)

      val.treeBuildConfig = _.isEmpty(val.treeBuildConfig) ? {} : val.treeBuildConfig
      const config = val.treeBuildConfig
      this.name = _.isNull(val.name) ? this.name : val.name
      this.checkType = _.isNull(config.checkType) ? this.checkType : config.checkType
      this.edit = _.isNull(config.isEdit) ? this.edit : config.isEdit
      this.drag = _.isNull(config.isDrag) ? this.drag : config.isDrag
      this.editShowType = _.isNull(config.editShowType) ? this.editShowType : config.editShowType
      this.mode = _.isNull(config.mode) ? this.mode : config.mode
      this._beforeDrop=config.beforeDrop;
      this._beforeDrag=config.beforeDrag;
      this._beforeDblClick=config.beforeDblClick;//onDblClick
      this._onDblClick=config.onDblClick;
      this.handleCreated()
      if(!_.isEmpty(val.treeConfigKey)){
        this.treeConfigKey=val.treeConfigKey;
      }else{
        this.treeConfigKey=null;
      }
      if(!_.isEmpty(config.settings) && !_.isEmpty(config.settings.callback)){
        this.setting.callback=Object.assign(this.setting.callback,config.settings.callback);
      }
      if(config.iconMap){
        this.setting.data.iconMap=Object.assign(this.setting.data.iconMap,config.iconMap)
      }
      let that = this
      if (!_.isEmpty(config.options)) {
        _.forEach(config.options, function(value, key) {
          that.setting[key] = config.options[key]
        })
      }

      if (this.edit === true) {
        // 是否编辑配置
        this.configParamsEdit(this)
      }
      if (this.edit === true) {
        // 是否拖拽配置
        this.configParamsDrag(this)
      }
      if(!_.isEmpty(val.dataUrl)){
        this.dataUrl=val.dataUrl;
      }else{
        this.dataUrl=getRealUrl('normalDicTree',true,{urlparam:[this.treeConfigKey]});
        let t=this;

        let setting=Object.assign({},this.setting,{async:{
          enable:true,
         // dataRoot:config.dataRoot?config.dataRoot:'data',
          otherParam:config.dealTreaparam!=undefined?config.dealTreaparam:this.dealTreaparam,
          dataFilter: config.dataFilter?config.dataFilter:function(treeid,pnode,resdata){
            if(resdata && resdata.data&& resdata.data.length>0){
              let _val=t.value?t.value.split(","):[];
              t.$_.forEach(resdata.data,(item,val)=>{
                // item.name=item.text;
                // item.pid=item.fid;
                // item.isParent=true;
                 if(item.leaf=='0')item.isParent=true

              })
            }else{
              if(pnode)
              pnode.isParent=false;
            }
              return resdata.data;
          },
          url:this.dataUrl
        }});
        // setting.async=
        // this.$set(setting.async,"otherParam",config.dealTreaparam!=undefined?config.dealTreaparam:this.dealTreaparam)
        this.setting=setting;
        return;
      }
      if(val.async!=undefined){
        this.async=val.async;
      }else{
        this.async=null;
      }
      // if(val.treeData){
      //   this.treeData=val.treeData;
      //   let $t=this;
      //   setTimeout(
      //     function(){
      //       $t.$refs.tree.loadData(val.treeData);
      //     },20
      //   )
      // }else{
      //   if(this.treeConfigKey){
      //     this.loadConfig();
      //   }else{
      //     this.loadTreeData({})
      //   }
      // }
      // this.treeData = _.isEmpty(val.treeData) ? [] : val.treeData;



    },
    dealTreaparam(treeid,node){
      if(node==undefined){
        return {p0:""}
      }else{
        return {p0:node.id};
      }
    },
    selectNode(nodeid){
      if(this.ztreeObj){
      let node=this.ztreeObj.getNodeByParam("id",nodeid);
      this.ztreeObj.selectNode(node);
      }else{
        let t =this;
        setTimeout(function(){
          let node=t.ztreeObj.getNodeByParam("id",nodeid);
          t.ztreeObj.selectNode(node);
        },20)
      }
    },
    handleCreated: function(ztreeObj) {
      this.ztreeObj = ztreeObj
      this.$emit('handleCreated', ztreeObj)
    },
    configParamsDrag: function(that) {
      if (that.setting.edit === undefined) {
        that.setting.edit = {}
      }
      that.setting.edit.drag = {
        autoExpandTrigger: true,
        // 1. true / false 分别表示 允许 / 不允许 移动到目标节点前面
        prev: that.dropPrev,
        // true / false 分别表示 允许 / 不允许 成为目标节点的子节点
        inner: that.dropInner,
        // true / false 分别表示 允许 / 不允许 移动到目标节点后面
        next: that.dropNext
      }
      const tempDragConfig = {
        beforeDrag: this.beforeDrag,
        beforeDrop: this.beforeDrop,
        beforeDragOpen: this.beforeDragOpen,
        onDrag: this.onTreeDrag,
        onDrop: this.onTreeDrop,
        onExpand: this.onExpand
      }
      _.forEach(tempDragConfig, function(value, key) {
        // console.log(key,value);
        that.setting.callback[key] = tempDragConfig[key]
      })
    },
    configParamsEdit: function(that) {
      that.setting.edit = {
        enable: true
      }
      if (this.editShowType === 1 || this.editShowType === 3) {
        const editTypeOne = {
          editNameSelectAll: true,
          showRemoveBtn: that.showRemoveBtn,
          showRenameBtn: that.showRenameBtn
        }

        that.setting.edit = {
          ...that.setting.edit,
          ...editTypeOne
        }
        const viewTempConfig = {
          addHoverDom: this.addHoverDom,
          removeHoverDom: this.removeHoverDom,
          selectedMulti: false
        }
        if (that.setting.view === undefined) {
          that.setting.view = {}
        }
        that.setting.view = {
          ...that.setting.view,
          ...viewTempConfig
        }
      } else {
        const editTypeOne = {
          editNameSelectAll: true,
          showRemoveBtn: false,
          showRenameBtn: false
        }
        that.setting.edit = {
          ...that.setting.edit,
          ...editTypeOne
        }
      }
      let tempConfig = {
        beforeDrag: that.beforeDrag,
        beforeEditName: that.beforeEditName,
        beforeRemove: that.beforeRemove,
        beforeRename: that.beforeRename,
        onRemove: that.onRemove,
        onRename: that.onRename
      }
      if (this.editShowType === 2 || this.editShowType === 3) {
        tempConfig = {
          ...tempConfig,
          onRightClick: that.onRightClick
        }
      }
      // eslint-disable-next-line no-undef
      _.forEach(tempConfig, function(value, key) {
        // console.log(key,value);
        that.setting.callback[key] = tempConfig[key]
      })
    },
    refresh(parentNode){
      parentNode=parentNode||""
      this.$refs.tree.reAsyncChildNodesPromise(parentNode);
    },
    // 单选多选配置
    configParamsCheckType: function(that) {
      switch (that.checkType) {
        case 'no':
          that.setting.check = {
            enable: false
          }
          break
        case 'check':
          let checkType=that.setting.checkType||{ 'Y': 'ps', 'N': 'ps' }
          that.setting.check = {
            chkboxType: checkType,
            enable: true
          }
          break
        case 'radio-all':
          that.setting.check = {
            radioType: 'all',
            chkStyle: 'radio',
            enable: true
          }
          break
        case 'radio-level':
          that.setting.check = {
            radioType: 'level',
            chkStyle: 'radio',
            enable: true
          }
          break
      }
    },
    showRemoveBtn: function(treeId, treeNode) {
      this.$emit('showRemoveBtn', treeId, treeNode)
      return !treeNode.isFirstNode
    },
    showRenameBtn: function(treeId, treeNode) {
      this.$emit('showRenameBtn', treeId, treeNode)
      // showRenameBtn 对 isLastNode = true 的节点不显示编辑按钮
      return !treeNode.isLastNode
    },

    //* *******************右键功能菜单**************************

    onTreeRightClick: function(event, treeId, treeNode) {
      if (!treeNode && event.target.tagName.toLowerCase() !== 'button' && $(event.target).parents('a').length === 0) {
        this.ztreeObj.cancelSelectedNode()
        this.onContextMenu('root', event, treeId, treeNode)
      } else if (treeNode && !treeNode.noR) {
        this.ztreeObj.selectNode(treeNode)
        this.onContextMenu('node', event, treeId, treeNode)
      }
    },
    onContextMenu(showFlag, event, treeId, treeNode) {
      const title = '节点'
      const isDisabled = _.isEqual(showFlag, 'root')
      const defaultItems = {
        items: [
          {
            label: '新增' + title,
            onClick: () => {
              this.addTreeNode()
            },
            disabled: isDisabled
          },
          {
            label: '修改' + title,
            onClick: () => {
              this.updateTreeNode()
            },
            disabled: isDisabled
          },
          {
            label: '删除' + title,
            onClick: () => {
              this.removeTreeNode()
            },
            disabled: isDisabled
          }
        ],
        event,
        x: event.clientX,
        y: event.clientY,
        customClass: 'class-a',
        zIndex: 3,
        minWidth: 230
      }
      /**
       * 传到父组件的参数是 名字,按钮,判断类型 root 是根节点  node 是普通节点 , treeId  选中的节点
       */

      const params = {
        title: title,
        items: defaultItems.items,
        showFlag: showFlag,
        treeId: treeId,
        treeNode: treeNode,
        ztreeObj: this.ztreeObj
      }

      this.$emit('createRightMenu', params)
      defaultItems.items = params.items
      defaultItems.event=event;
      defaultItems.data=treeNode
      if(defaultItems.items&&defaultItems.items.length>0)
      this.$contextmenu(defaultItems)
      return false
    },
    addTreeNode: function() {
      const id = this.guid()
      var newNode = { id: id, name: '新增节点:' + id }
      if (this.ztreeObj.getSelectedNodes()[0]) {
        newNode.checked = this.ztreeObj.getSelectedNodes()[0].checked
        this.ztreeObj.addNodes(this.ztreeObj.getSelectedNodes()[0], newNode)
        var node = this.ztreeObj.getNodeByParam('id', newNode.id, null)
        this.ztreeObj.selectNode(node)
        this.ztreeObj.editName(node)
      } else {
        this.ztreeObj.addNodes(null, newNode)
        var node2 = this.ztreeObj.getNodeByParam('id', newNode.id, null)
        this.ztreeObj.selectNode(node2)
        this.ztreeObj.editName(node2)
      }
    },
    updateTreeNode: function() {
      const nodes = this.ztreeObj.getSelectedNodes()
      const treeNode = nodes[0]
      if (_.isEqual(nodes.length, 0)) {
        this.$message({
          type: 'info',
          message: '请先选择一个节点'
        })
        return
      }
      this.ztreeObj.editName(treeNode)
    },

    removeTreeNode: function() {
      const that = this
      // debugger;
      const nodes = this.ztreeObj.getSelectedNodes()
      this.beforeTreeRemove(this.ztreeObj.setting.treeId, nodes[0], function(flag) {
        // debugger;
        if (!flag) {
          return
        }
        if (nodes && nodes.length > 0) {
          if (nodes[0].children && nodes[0].children.length > 0) {
            that.$confirm(
              '要删除的节点是父节点，如果删除将连同子节点一起删掉。请确认！',
              '提示',
              {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                closeOnPressEscape: false,
                closeOnClickModal: false,
                type: 'warning'
              })
              .then(() => {
                that.ztreeObj.removeNode(nodes[0])
              })
              .catch(() => {
                // debugger;
                that.$message({
                  type: 'info',
                  message: '已取消删除'
                })
              })
          } else {
            that.ztreeObj.removeNode(nodes[0])
          }
        }
      })
    },

    //* *****************右键功能菜单*********************

    // 1.删除前提醒
    beforeTreeRemove: function(treeId, treeNode, callback) {
      // var zTree = $.fn.zTree.getZTreeObj("treeDemo");
      // debugger;
      this.ztreeObj.selectNode(treeNode)
      this.$confirm(
        '确认删除数据:[' + treeNode.name + ']！删除后将无法恢复，是否继续？',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          closeOnPressEscape: false,
          closeOnClickModal: false,
          type: 'warning'
        })
        .then(() => {
          callback(true)
          this.$emit('beforeRemove', treeId, treeNode)
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
          callback(false)
        })
    },
    // 1. 创建节点 DOM 后， 弹出该节点的 tId、name 的信息
    onRemove: (event, treeId, treeNode) => {
      this.$emit('onRemove', ...event, treeId, treeNode)
    },
    beforeRename: function(treeId, treeNode, newName) {
      // debugger;
      if (_.isEqual(newName.length, 0)) {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
        this.ztreeObj.selectNode(treeNode)
        setTimeout(function() {
          this.ztreeObj.editName(treeNode)
        }, 10)
        return false
      }
      return true
    },
    // 1. 修改名称后，弹出被修改名称的节点的 tId 以及 name 信息
    onRename: function(event, treeId, treeNode, isCancel) {
      // 更新成功

      this.$emit('onRename', event, treeId, treeNode, isCancel)
    },
     beforeDrop(event, treeId, treeNodes, targetNode, moveType) {
       if(this._beforeDrop && this._beforeDrop(treeId,treeNodes,targetNode)==false)return false;
      return true;
    },
    // 1.禁止全部拖拽操作 false 打开拖拽功能 true
    beforeDrag: function(treeId, treeNodes) {
       if(this._beforeDrag && this._beforeDrag(treeId,treeNodes)==false)return false;
      for (var i = 0, l = treeNodes.length; i < l; i++) {
        if (treeNodes[i].drag === false) {
          this.curDragNodes = null
          return false
        } else if (treeNodes[i].parentTId && treeNodes[i].getParentNode().childDrag === false) {
          this.curDragNodes = null
          return false
        }
      }
      this.curDragNodes = treeNodes
      return true
    }, confirmEdit: function(treeNode, treeId, callback) {
      this.$confirm('[' + treeNode.name + ']将进入编辑状态！是否进入编辑？',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          closeOnPressEscape: false,
          closeOnClickModal: false,
          type: 'warning'
        })
        .then(() => {
          this.$emit('beforeEditName', treeId, treeNode)
          callback(true)
        })
        .catch(() => {
          // debugger;
          this.$message({
            type: 'info',
            message: '已取消编辑状态'
          })
          callback(false)
        })
    }, beforeEditName: function(treeId, treeNode) {
      // showLog("[ "+getTime()+" beforeEditName ]&nbsp;&nbsp;&nbsp;&nbsp; " + treeNode.name);
      let flag = false
      this.ztreeObj.selectNode(treeNode)
      this.confirmEdit(treeNode, treeId, function(f) {
        flag = f
      })
      return flag
    },
    // 拖拽
    dropPrev: function(treeId, nodes, targetNode) {
      // return !targetNode.isParent;
      var pNode = targetNode.getParentNode()
      if (pNode && pNode.dropInner === false) {
        return false
      } else {
        for (var i = 0, l = this.curDragNodes.length; i < l; i++) {
          var curPNode = this.curDragNodes[i].getParentNode()
          if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
            return false
          }
        }
      }
      return true
    },
    /**
     * 用于捕获拖拽节点移动到折叠状态的父节点后，即将自动展开该父节点之前的事件回调函数，并且根据返回值确定是否允许自动展开操作
     */
    beforeDragOpen: function(treeId, treeNode) {
      this.autoExpandNode = treeNode
      return true
    },
    dropInner: function(treeId, nodes, targetNode) {
      // return !(targetNode && targetNode.level === 0);
      if (targetNode && targetNode.dropInner === false) {
        return false
      } else {
        for (var i = 0, l = this.curDragNodes.length; i < l; i++) {
          if (!targetNode && this.curDragNodes[i].dropRoot === false) {
            return false
          } else if (this.curDragNodes[i].parentTId && this.curDragNodes[i].getParentNode() !== targetNode && this.curDragNodes[i].getParentNode().childOuter === false) {
            return false
          }
        }
      }
      return true
    },
    dropNext: function(treeId, nodes, targetNode) {
      // return !targetNode.isParent;
      var pNode = targetNode.getParentNode()
      if (pNode && pNode.dropInner === false) {
        return false
      } else {
        for (var i = 0, l = this.curDragNodes.length; i < l; i++) {
          var curPNode = this.curDragNodes[i].getParentNode()
          if (curPNode && curPNode !== targetNode.getParentNode() && curPNode.childOuter === false) {
            return false
          }
        }
      }
      return true
    },
    addHoverDom: function(treeId, treeNode) {
      const that = this
      // var sObj = $("#" + treeNode.tId + "_span");
      var sObj = $('#' + treeNode.tId + '_span')
      if (treeNode.editNameFlag || $('#addBtn_' + treeNode.id).length > 0) return
      var addStr = '<span class=\'button add\' id=\'addBtn_' + treeNode.id +
        '\' title=\'添加\' onfocus=\'this.blur();\'>添加</span>'
      sObj.after(addStr)
      var btn = $('#addBtn_' + treeNode.id)
      if (btn) {
        btn.bind('click', function() {
          that.ztreeObj.addNodes(treeNode, { id: that.guid(), pId: treeNode.id, name: '新增节点:' + that.guid() })
          return false
        })
      }
    },
    removeHoverDom: function(treeId, treeNode) {
      $('#addBtn_' + treeNode.id).unbind().remove()
    },
    //节点双击之前事件,返回 true和false,true触发双击之后回调函数，false不触发双击之后回调函数
    beforeDblClick:function(treeId,treeNode){
      if(this._beforeDblClick && this._beforeDblClick(treeId,treeNode)==false)return false;
      return true;
    },
    //双击之后回调函数
    onDblClick:function(event, treeId, treeNode){
      if(this._onDblClick && this._onDblClick(event,treeId,treeNode)==false)return false;
      return true;
    },
    // 1. 每次点击 checkbox 或 radio 后， 弹出该节点的 tId、name 以及当前勾选状态的信息
    onTreeCheck: function(event, treeId, treeNode) {

      this.$emit('onTreeCheck', event, treeId, treeNode)
    },
    // 每次点击节点后， 弹出该节点的 tId、name 的信息
    onTreeClick: function(event, treeId, treeNode) {
      this.$emit('onTreeClick', event, treeId, treeNode)
    },
    // 1. 每次折叠节点后， 弹出该节点的 tId、name 的信息
    onTreeCollapse: function(event, treeId, treeNode) {
      this.$emit('onTreeCollapse', event, treeId, treeNode)
    },
    // 1. 每次鼠标双击后， 弹出鼠标所在节点的 tId、name 的信息
    onTreeDblClick: function(event, treeId, treeNode) {
      this.$emit('onTreeDblClick', event, treeId, treeNode)
    },
    // 1. 每次开始进行拖拽节点后， 弹出被拖拽节点的个数信息
    onTreeDrag: function(event, treeId, treeNodes) {
      this.$emit('onTreeDrag', event, treeId, treeNodes)
    },
    // 1. 拖拽节点时，随时输出 当前拖拽到的目标 DOM
    onTreeDragMove: function(event, treeId, treeNodes) {
      this.$emit('onTreeDragMove', event, treeId, treeNodes)
    },

    // 1. 每次拖拽操作结束后， 弹出该被拖拽节点的个数以及目标节点的 tId、name 的信息
    onTreeDrop: function(event, treeId, treeNodes, targetNode, moveType) {
      this.$emit('onTreeDrop', event, treeId, treeNodes, targetNode, moveType)
    },
    // 1. 每次展开节点后， 弹出该节点的 tId、name 的信息
    onTreeExpand: function(event, treeId, treeNode) {
      this.$emit('onTreeExpand', event, treeId, treeNode)
    },
    // 1. 每次鼠标按键按下后， 弹出鼠标所在节点的 tId、name 的信息
    onTreeMouseDown: function(event, treeId, treeNode) {
      this.$emit('onTreeMouseDown', event, treeId, treeNode)
    },
    // 1. 每次鼠标按键松开后， 弹出鼠标所在节点的 tId、name 的信息
    onTreeMouseUp: function(event, treeId, treeNode) {
      this.$emit('onTreeMouseUp', event, treeId, treeNode)
    },
    guid: function() {
      // debugger;
      const id = new SnowflakeId()
      return id.generate()
    },
    getCheckedNodes(){
      if(this.ztreeObj)
      return this.ztreeObj.getCheckedNodes();
      return null;
    },
  }
}
</script>
<style lang="scss" scoped>
.ztree li span.button.add {
  margin-left: 2px;
  margin-right: -1px;
  background-position: -144px 0;
  vertical-align: top;
  *vertical-align: middle
}

.item {
  padding: 0px 0;
}

/*.box-card {*/
/*    position:absolute; top:0;text-align: left;padding: 2px;*/
/*}*/
.box-card ul {
  margin: 0px 0;
  padding: 0 0px;
}

::v-deep .el-card__body {
  margin: 0px 0 !important;
  padding: 0 0px !important;
  font-size: 16px !important;
}

.box-card ul li {
  margin: 1px 0;
  padding: 0 5px;
  cursor: pointer;
  list-style: none outside none;
}
</style>
